﻿module StochasticSimulation.SSA.ReactionGraph.Tests

open StochasticSimulation.ChemicalReaction.PriorityQueue
open StochasticSimulation.ChemicalReaction.ReactionGraph
open StochasticSimulation.ChemicalReaction.ChemicalReaction
open StochasticSimulation.ChemicalReaction.ChemicalSpecies
open System.Collections.Generic
open NUnit.Framework
open System;

[<TestFixture>] 
type ``Given a List of reactions`` ()= class
    
    let reactions = [
    (*r1*)    { Rate = 10000.0 ; Changes = dict[ {Name = "I"}, {Destroyed =0 ; Created=1}] }; (* affects r2, r4 only *)
    (*r2*)    { Rate = 1000.0 ; Changes = dict[ {Name = "I"}, {Destroyed =1 ; Created=0} ; {Name = "P"}, {Destroyed =0 ; Created=1} ] };
    (*r3*)    { Rate = 1.0 ; Changes = dict[ {Name = "P"}, {Destroyed =1 ; Created=0}] };
    (*r4*)    { Rate = 9900.0 ; Changes = dict[ {Name = "I"}, {Destroyed =1 ; Created=0} ; {Name = "S"}, {Destroyed =1 ; Created=1} ] };
    (*r5*)    { Rate = 10000.0 ; Changes = dict[ {Name = "S"}, {Destroyed =0 ; Created=1}] };  
    (*r6*)    { Rate = 1000.0 ; Changes = dict[ {Name = "S"}, {Destroyed =1 ; Created=0}] }  (* affects r4, r6 only *)
        ]

    [<Test>] 
    member test.`` initialise a graph with edges between the affected reactions.`` ()=
        let graph = new Graph(reactions)
        let connections = graph.Connections()
        Assert.AreEqual( List.length connections, List.length reactions )
        let firstConnection = List.head connections
        Assert.AreEqual(List.length (snd firstConnection), 2)
   
    [<Test>] 
    member test.`` find the edges from a particular reaction including self.`` ()=
        let graph = new Graph(reactions)
        let affected = graph.GetAffected( reactions.[5] )
        Assert.AreEqual( List.length affected, 2)
        Assert.AreEqual( affected.[0].ToString(), reactions.[3].ToString() )
        Assert.AreEqual( affected.[1].ToString(), reactions.[5].ToString() ) // affects itself
    
    
    [<Test>] 
    member test.`` find the edges from a particular reaction.`` ()=
        let graph = new Graph(reactions)
        let affected = graph.GetAffected( reactions.[0] )
        Assert.AreEqual( List.length affected, 2)
        Assert.AreEqual( affected.[0].ToString(), reactions.[1].ToString() )
        Assert.AreEqual( affected.[1].ToString(), reactions.[3].ToString() )         
                
    [<Test>] 
    member test.`` find no edges from a reaction that affects nothing else.`` ()=
        let graph = new Graph(reactions)
        let affected = graph.GetAffected( reactions.[2] )
        Assert.AreEqual( List.length affected, 1)
        Assert.AreEqual( affected.[0].ToString(), reactions.[2].ToString() )

    [<Test>]
    member test.`` place in sorted queue and find next`` ()=
        let q = new PriorityQueue([], reactions)
        let newTimes = [0.1;0.2;0.3;0.01;0.5;0.6]
        let updates = List.zip reactions newTimes
        Assert.AreEqual( fst q.Next, reactions.[3] )
        
end

[<TestFixture>] 
type ``Given a ReactionGraph that has at least one reaction`` ()= class
    //let graph = 
    [<Test>] 
    member test.`` add a new reaction and update Depends correctly.`` ()=
        Assert.AreEqual(1,0)


    [<Test>] 
    member test.`` add a new reaction and update Updates correctly.`` ()=
        Assert.AreEqual(1,0)

//    [<Test>] 
//    member test.`` calcualte the propensity correctly for single species being created.`` ()=
        
end